VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "VBLine"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit

Private mText As String
Private mOrigText As String
Private maDecVars() As String
Private maWords() As String
Private mWordCount As Long
Private mSplitter As TextSplitter
Private mDecVarCount As Long
Private mHasContinuation As Boolean

Const kContinuation As String = " _"
Const dblQt = """"

Public Sub ReadALineFrom(inputStream As TextStream)

    Text = inputStream.ReadLine

    Do While Not inputStream.AtEndOfStream And mHasContinuation
    
        AddText inputStream.ReadLine
    
    Loop

End Sub

Public Property Get DeclaredVariableCount() As Long
    DeclaredVariableCount = mDecVarCount
End Property

Public Property Get DeclaredVariable(which As Long) As String
    If which < 1 Or which > mDecVarCount Then
        DeclaredVariable = ""
    Else
        DeclaredVariable = maDecVars(which)
    End If
End Property

Private Sub Reset()

    mOrigText = ""
    mText = ""
    mWordCount = 0
    mDecVarCount = 0
    Erase maDecVars
    Erase maWords
    
End Sub

Public Function HasContinuation() As Boolean
    HasContinuation = mHasContinuation
End Function

Public Sub AddText(theText As String)

On Error GoTo Catch

    mOrigText = mOrigText & theText
    
    mHasContinuation = LineContinues
    
    If mHasContinuation Then
        RemoveContinuationIndicator
    Else
        RecordCompleteLineInfo
    End If
    
Finally:
    On Error GoTo 0
    Exit Sub
    
Catch:
    MsgBox "VBLine.AddText: " & Err.Description
    GoTo Finally

End Sub

Private Sub RemoveContinuationIndicator()
    mOrigText = Left(mOrigText, Len(mOrigText) - 1)
End Sub

Private Sub RecordCompleteLineInfo()

    mText = LCase(Trim(mOrigText))
    
    mSplitter.LoadText mText, " ,"
    
    mWordCount = mSplitter.WordCount
    
    If Not IsAComment Then
        StripTrailingComment
    End If
    
    If IsADeclaration Then
        ExtractDeclaredVariables
    End If
        
End Sub

Private Sub StripTrailingComment()

Dim idx As Long

    idx = InStr(mOrigText, "'")
    If idx > 1 Then
        mOrigText = Left(mOrigText, idx - 1)
    End If

End Sub

Private Function LineContinues() As Boolean

    If Right(mOrigText, 2) = kContinuation Then
        LineContinues = True
    Else
        LineContinues = False
    End If

End Function

Public Property Let Text(theText As String)

    Reset

    AddText theText

End Property

Public Property Get Text() As String

    Text = mOrigText
    
End Property

Public Function IsProcHeaderLine() As Boolean

Dim word1qualifies As Boolean
Dim words1and2qualify As Boolean

    word1qualifies = WordInList(1, Array("sub", "property", "function"))
    words1and2qualify _
        = WordInList(1, Array("public", "private", "friend", "static")) _
        And WordInList(2, Array("sub", "property", "function"))
        
    IsProcHeaderLine = word1qualifies Or words1and2qualify
    
End Function

Public Function IsProcEndLine() As Boolean

    IsProcEndLine = WordInList(1, Array("end")) And WordInList(2, Array("sub", "function", "property"))
    
End Function

Public Function IsADoingLine() As Boolean

    If IsAComment() _
    Or Len(mText) = 0 _
    Or IsADeclaration() _
    Or IsProcHeaderLine() _
    Or IsProcEndLine() Then
        IsADoingLine = False
    Else
        IsADoingLine = True
    End If

End Function

Public Function IsAComment() As Boolean

    If Left(mText, 1) = "'" _
    Or Left(mText, 4) = "rem " _
    Or mText = "rem" Then
        IsAComment = True
    Else
        IsAComment = False
    End If

End Function

Public Function IsAnIf() As Boolean

    IsAnIf = (mSplitter.Word(1) = "if")

End Function

Public Function IsAnElseIf() As Boolean

    IsAnElseIf = (mSplitter.Word(1) = "elseif")

End Function

Public Function IsALoopStart() As Boolean

    IsALoopStart = (InStr("for|do|while", mSplitter.Word(1)) > 0)

End Function

Public Function HasAGoto() As Boolean

Dim idxWord As Long

    For idxWord = 1 To mSplitter.WordCount - 1
        If mSplitter.Word(idxWord) = "goto" Then
            HasAGoto = True
        End If
    Next
    
End Function

Public Function IsADeclaration() As Boolean

Dim word1 As String
Dim word2 As String

    word1 = mSplitter.Word(1)
    Select Case word1
    Case "public", "private", "global", "friend", "static"
        If "const" = mSplitter.Word(2) Then
            IsADeclaration = False
        Else
            If Not IsProcHeaderLine Then
                IsADeclaration = True
            Else
                IsADeclaration = False
            End If
        End If
    Case "dim"
        IsADeclaration = True
    End Select

End Function

Public Function IsGlobal() As Boolean

    Select Case mSplitter.Word(1)
    Case "public", "global"
        IsGlobal = True
    End Select
    
End Function

Private Sub ExtractDeclaredVariables()
    
Dim arrClauses As Variant
Dim arrClauseWords As Variant
Dim clause As Long
    
    arrClauses = Split(mOrigText, ",")
    
    For clause = LBound(arrClauses) To UBound(arrClauses)
    
        arrClauseWords = Split(Trim(CStr(arrClauses(clause))), " ")
            
        If clause > LBound(arrClauses) Then
            AddDeclaredVariable CStr(arrClauseWords(0))
        Else
            AddDeclaredVariable CStr(arrClauseWords(1))
        End If
    
    Next
    
End Sub

Private Sub AddDeclaredVariable(newVarName As String)

    mDecVarCount = mDecVarCount + 1
    ReDim Preserve maDecVars(mDecVarCount)
    maDecVars(mDecVarCount) = newVarName

End Sub

Public Function IsAnIif() As Boolean

    If InStr(mText, " iif(") > 0 Then
        IsAnIif = True
    Else
        IsAnIif = False
    End If

End Function

Public Function CodeLength() As Long
    CodeLength = Len(mText)
End Function

Private Function WordInList(whichWord As Long, list As Variant) As Boolean

Dim Word As String
Dim idx As Long

    Word = mSplitter.Word(whichWord)

    WordInList = False

    For idx = 0 To UBound(list)
        If Word = list(idx) Then
            WordInList = True
            Exit Function
        End If
    Next

End Function

Public Property Get WordCount() As Long
    WordCount = mWordCount
End Property

Public Property Get TextWord(which As Long) As String

    TextWord = mSplitter.Word(which)

End Property

Private Sub Class_Initialize()
    Set mSplitter = New TextSplitter
End Sub

Private Sub Class_Terminate()
    Set mSplitter = Nothing
End Sub
